ARC097 D - Equals
https://atcoder.jp/contests/arc097/tasks/arc097_b
提出
code: python
n, m = map(int, input().split())
p = list(map(int, input().split()))
xy = list(map(int, input().split())) for _ in range(m)
# UnionFindをどう使うか
解答
code: python
n, m = map(int, input().split())
p = list(map(int, input().split()))
xy = list(map(int, input().split())) for _ in range(m)
class UnionFind:
def __init__(self, n):
self.parent = i for i in range(n)
self.rank = 0 * n
self.size = 1 * n
def root(self, x):
if self.parentx == x:
return x
else:
self.parentx = self.root(self.parentx)
return self.parentx
def union(self, x, y):
x = self.root(x)
y = self.root(y)
if x == y:
return
if self.rankx < self.ranky:
self.parentx = y
self.sizey += self.sizex
else:
self.parenty = x
self.sizex += self.sizey
if self.rankx == self.ranky:
self.rankx += 1
def same(self, x, y):
return self.root(x) == self.root(y)
uf = UnionFind(n + 1)
# 入れ替え可能ならば同じ集合に属している
# 同じ集合に属する数字は、たとえ直接は入れ替えできなくとも、その中で好きなように並べなおすことが可能
for x, y in xy:
uf.union(x, y)
ans = 0
# 例えば idx=1 を考えると 1 が属する集合と、p1=5 が属する集合が同じであれば、5 を p5 の位置に持ってくることが可能
for idx, v in enumerate(p):
if uf.same(idx + 1, v):
ans += 1
print(ans)
テーマ
#UnionFind
蟻本 2-4 食物連鎖
メモ
ARC 097